package org.mtmi.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.mtmi.ui.controls.Control;
import org.mtmi.ui.scenes.Scene;
import org.mtmi.ui.scenes.SceneManager;

/**
 * The role of this class is to save a Scene to a file.
 */
public class SceneWriter 
{
	private Scene scene;

	public SceneWriter( Scene s ) 
	{
		scene = s;
	}
	
	/** @return the control's id, can be used to save links between controls */ 
	public int getControlId( Control c ) 
	{
		int id = c.getData( D_ID, 0 );
		if( id == 0 ) {
			throw new Error("ID is not defined for control"); //$NON-NLS-1$
		}
		return id;
	}

	static final String E_SCENE    = "scene"; //$NON-NLS-1$
	static final String E_CONTROLS = "controls"; //$NON-NLS-1$
	static final String E_CONTROL = "control"; //$NON-NLS-1$
	static final String E_CONTENTS = "contents"; //$NON-NLS-1$
	static final String E_DATA = "data"; //$NON-NLS-1$
	static final String E_BACKGROUND = "background"; //$NON-NLS-1$
	
	static final String A_ID = "id"; //$NON-NLS-1$
	static final String A_CLASS = "class"; //$NON-NLS-1$
	static final String A_FLAGS = "flags"; //$NON-NLS-1$
	static final String A_CONTROL = "control"; //$NON-NLS-1$
	static final String A_KEY = "key"; //$NON-NLS-1$
	
	static final String D_ID = "id@SceneSaver"; //$NON-NLS-1$
	
	/**
	 * Process save of the scene
	 */
	public void save()
	{
		if( scene.getFileName() == null ) {
			//this scene cannot be saved.
			return ;
		}
		
		try {
			
			String fullname = SceneManager.getDefault().getSceneDirectory()+File.separator+scene.getFileName();
			FileOutputStream fos = new FileOutputStream( fullname );
			XMLWriter xp = new XMLWriter( fos );
			
			xp.startElement( E_SCENE );
			
			//scene background image
			if( scene.getBackgroundKey()!=null ) {
				xp.addElement( E_BACKGROUND, A_KEY, scene.getBackgroundKey() );
			}
			
			//save control id map 
			xp.startElement( E_CONTROLS );
			
			int id = 1;
			for( Control c : scene.getControls( false ) ) {
				c.setData( D_ID, id );
				xp.addElement( E_CONTROL, A_ID, id, A_CLASS, c.getClass().getName(), A_FLAGS, c.getFlags() );
				id++;
			}
			xp.endElement( E_CONTROLS );

			//save controls data:
			xp.startElement( E_CONTENTS );
			for( Control c : scene.getControls( false ) ) {
				IControlIO w = (IControlIO)c.getAdapter( IControlIO.class, null );
				if( w!=null ) {
					xp.startElement( E_DATA );
					xp.addAttr( A_CONTROL, c.getData( D_ID, 0 ) );
					w.writeControl( c, xp, this );
					xp.endElement( E_DATA );
				}
			}
			xp.endElement( E_CONTENTS );
			
			xp.endElement( E_SCENE);
			
			//reset id:
			for( Control c : scene.getControls( false ) ) {
				c.removeData( D_ID );
			}
			
		} catch( IOException x ) {
			x.printStackTrace(); //TODO a log file ???
		}
	}
}
